function fors = fors(N,b=1,e=0.1, epocas=100)
%alpha=0.9;
cantAciertos=0;
TANH=1;
EXP=2;
LINEAL=3;
FUNC=TANH;

N=[1 N 1];					
% la funcion es de R->R por lo que es siempre UNA entrada y UNA salida, lo que pasamos por parametro ahora son 
% las capas intermedias por ejemplo [2] significa una capa oculta con 2 neuronas (mas la capa de entrada y la capa de salida con una neurona cada una)

for c=1:length(N)-1
	w{c} = (rand(N(c+1),N(c)+1)-0.5); %el +1 es por el umbral.
	w{c} = w{c} ./ 100;
endfor

psi=[(37:0.05:45)']; %uniforme
%psi=[(0:0.05:4)']; %uniforme
%psi=[(15:0.3:19)';(19:0.1:21)';(21:0.3:28)';(28:0.1:30)';(30:0.3:35)';(35:0.1:45)'];  %personalizado
%psi=[(-2*pi:0.1:2*pi)'];

%Para las salidas se aplica directamente la funcion al vector (funcion nro 9)
s=f(psi); 		

%Actualmente esta funcion devuelve psi completo, mas adelante hay que elegir un subconjunto
psiTraining=getPsiTraining(psi);	
sTraining=f(psiTraining);		

errorAnt=errorAnt_old=0;
v=v_old=[];
for in=1:rows(psiTraining)	
	%v
	%v_old
	v{1}=horzcat(psiTraining(in,:),-1); %seteo el inicixal
	v_old{1}=horzcat(psiTraining(in,:),-1);
	for k=2:length(N)-1
		for i=1:N(k)
			h{k}(i)=0;
			for j=1:(N(k-1)+1)
				h{k}(i) = h{k}(i)+ w{k-1}(i,j)*v{k-1}(j);	
			endfor
			v{k}(i)=applyG(b, h{k}(i), FUNC);
			%v{k}(i)
			%v
		endfor
		
		v_old{k} = applyG(b, (w{k-1}*v_old{k-1}')', FUNC);
		if(in==1)
			v{k} = horzcat(v{k},-1);
		end
		v_old{k} = horzcat(v_old{k},-1);
	endfor
	
	for i=1:N(k+1) %deberia ser siempre 1
		h{k+1}(i)=0; %el h de la ultima capa
		for j=1:N(k)+1
			h{k+1}(i)=h{k+1}(i)+ w{k}(i,j)*v{k}(j);
		endfor
		salida = applyG(b, h{k+1}(i), LINEAL);
	endfor
	salida_old = applyG(b,(w{k}*v_old{k}')', LINEAL); %';
	
	errorpatronfin=(sTraining(in)-salida)^2;
	errorpatronfin_old=(sTraining(in)-salida_old)^2;
	
	errorAnt=errorAnt+errorpatronfin;
	errorAnt_old =errorAnt_old+errorpatronfin_old;
endfor

errorAnt=errorAnt/2

ep=0;
%errorAnt=0;
do
  indices = randperm(rows(psiTraining));

  erroracum=0;
  wold=w;
  for ind=1:rows(psiTraining)
	in=indices(ind);
	h=[];
	v=[];
	v{1}=horzcat(psiTraining(in,:),-1); %seteo el inicixal
	v_old{1}=horzcat(psiTraining(in,:),-1);
	
	for k=2:length(N)-1
		for i=1:N(k)
			h{k}(i)=0;
			for j=1:(N(k-1)+1)
				h{k}(i) = h{k}(i)+ w{k-1}(i,j)*v{k-1}(j);	
			endfor
			v{k}(i)=applyG(b, h{k}(i), FUNC);
			%v{k}(i)
			%v
		endfor
		
		v_old{k} = applyG(b, (w{k-1}*v_old{k-1}')', FUNC);
		v{k} = horzcat(v{k},-1);
		
		v_old{k} = horzcat(v_old{k},-1);
	endfor

	
	for i=1:N(k+1) %deberia ser siempre 1
		h{k+1}(i)=0; %el h de la ultima capa
		for j=1:N(k)+1
			h{k+1}(i)=h{k+1}(i)+ w{k}(i,j)*v{k}(j);
		endfor
		salida = v{k+1} = applyG(b, h{k+1}(i), LINEAL);
	endfor
	salida_old = v_old{k+1} = applyG(b,(w{k}*v_old{k}')', LINEAL); %';
	
	delta{k} = (sTraining(in)-v{k+1})*(applyGprima(b, h{k+1}, LINEAL)+0.1);

	for p=k-1:-1:1
		aux=0;
		for i=1:N(p+1)	% +1 por el umbral.
			for j=1:N(p+2)  %+1 porque no existe delta en la primer capa 
				aux=aux+(delta{p+1}(j)*w{p+1}(j,i));
			end
			delta{p}(i) = (applyGprima(b,h{p+1}(i),FUNC)+0.1)*aux;
		end		
	endfor

	for p=1:k
		aux=0;
		for i=1:columns(delta{p})
			for j=1:columns(v{p})
				aux=aux+delta{p}(i)*v{p}(j);
			end
			dw(i,j)=e*aux;
			w{p}(i,j)=w{p}(i,j)+dw(i,j);
		end
		
	endfor
	erroractual=(sTraining(in)-v{k+1})^2;
	if (isnan(erroractual))
		ep 
		delta
		ind
		v
		w
		return
	endif
	erroracum+=erroractual;
  endfor
  erroracum=erroracum/2;

  if (erroracum<errorAnt)
	errorAnt=erroracum;  
	cantAciertos=cantAciertos+1;
	if (cantAciertos>=1)
		e=e+0.001;
		cantAciertos=0;
	endif
  endif
  if (erroracum>errorAnt)
	w=wold;
	erroracum=errorAnt;  
	cantAciertos=0;
	if(e<0.0001)
		e=0.0001
	else
		e=e-(0.1*e);
	end
  endif

  if (mod(ep,1)==0)
	erroracum
	e
	plot(psiTraining(:,1)',sTraining,"3;esperada;", psiTraining(:,1)',aplicarRed(psiTraining,w,N,b), "1;out;")
	drawnow
	fflush(1);
  endif
  
  ep++;
until(ep==epocas || erroracum<=10e-3);
ep
erroracum

%salidafinal=[];
%for i=1:rows(psiTraining)	
%	patron=v{1}=horzcat(psiTraining(i,:),-1); %seteo el inicixal
%	for k=2:length(N)-1
%		v{k} = applyG(b, (w{k-1}*v{k-1}')', FUNC); %'
%		v{k} = horzcat(v{k},-1);
%	endfor
%	exitfunc = applyG(b,(w{k}*v{k}')', LINEAL); %'
%	salidafinal=[salidafinal, exitfunc];
%endfor


salidafinal=aplicarRed(psiTraining,w,N,b);

plot(psiTraining(:,1)',sTraining,"3;esperada;", psiTraining(:,1)',salidafinal, "1;out;"); %ploteo la funcion original y la salida para ver si aprendio la red

endfunction
		